<template>
  <div class="flow-designer">
    <div class="flow-toolbar">
      <el-button-group>
        <el-button @click="saveFlow" type="primary" :icon="Save">保存</el-button>
        <el-button @click="clearFlow" :icon="Delete">清空</el-button>
        <el-button @click="zoomIn" :icon="ZoomIn">放大</el-button>
        <el-button @click="zoomOut" :icon="ZoomOut">缩小</el-button>
        <el-button @click="fitView" :icon="FullScreen">适应画布</el-button>
      </el-button-group>
      
      <div class="flow-info">
        <span>节点数: {{ nodeCount }}</span>
        <span>连线数: {{ edgeCount }}</span>
      </div>
    </div>
    
    <div class="flow-container">
      <!-- 节点面板 -->
      <div class="node-panel">
        <div class="panel-title">节点库</div>
        <div class="node-list">
          <div 
            v-for="node in nodeTypes" 
            :key="node.type"
            class="node-item"
            :draggable="true"
            @dragstart="handleDragStart($event, node)"
          >
            <div class="node-icon" :class="node.iconClass">
              <i :class="node.icon"></i>
            </div>
            <div class="node-label">{{ node.label }}</div>
          </div>
        </div>
      </div>
      
      <!-- 画布区域 -->
      <div class="canvas-container">
        <div ref="flowContainer" class="flow-canvas"></div>
      </div>
      
      <!-- 属性面板 -->
      <div class="property-panel" v-if="selectedElement">
        <div class="panel-title">属性配置</div>
        <div class="property-content">
          <el-form :model="selectedElement" label-width="80px" size="small">
            <el-form-item label="ID">
              <el-input v-model="selectedElement.id" disabled></el-input>
            </el-form-item>
            <el-form-item label="名称">
              <el-input v-model="selectedElement.text" @input="updateElementText"></el-input>
            </el-form-item>
            <el-form-item label="类型" v-if="selectedElement.type">
              <el-input v-model="selectedElement.type" disabled></el-input>
            </el-form-item>
            
            <!-- 节点特有属性 -->
            <template v-if="selectedElement.type && selectedElement.type !== 'polyline'">
              <el-form-item label="描述">
                <el-input 
                  v-model="selectedElement.properties.description" 
                  type="textarea" 
                  :rows="3"
                  @input="updateElementProperties"
                ></el-input>
              </el-form-item>
              
              <!-- HTTP节点配置 -->
              <template v-if="selectedElement.type === 'http-node'">
                <el-form-item label="请求方法">
                  <el-select v-model="selectedElement.properties.method" @change="updateElementProperties">
                    <el-option label="GET" value="GET"></el-option>
                    <el-option label="POST" value="POST"></el-option>
                    <el-option label="PUT" value="PUT"></el-option>
                    <el-option label="DELETE" value="DELETE"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="请求URL">
                  <el-input v-model="selectedElement.properties.url" @input="updateElementProperties"></el-input>
                </el-form-item>
                <el-form-item label="请求头">
                  <el-input 
                    v-model="selectedElement.properties.headers" 
                    type="textarea" 
                    :rows="3"
                    placeholder="JSON格式"
                    @input="updateElementProperties"
                  ></el-input>
                </el-form-item>
              </template>
              
              <!-- 条件节点配置 -->
              <template v-if="selectedElement.type === 'condition-node'">
                <el-form-item label="条件表达式">
                  <el-input 
                    v-model="selectedElement.properties.condition" 
                    type="textarea" 
                    :rows="3"
                    @input="updateElementProperties"
                  ></el-input>
                </el-form-item>
              </template>
              
              <!-- 脚本节点配置 -->
              <template v-if="selectedElement.type === 'script-node'">
                <el-form-item label="脚本语言">
                  <el-select v-model="selectedElement.properties.language" @change="updateElementProperties">
                    <el-option label="JavaScript" value="javascript"></el-option>
                    <el-option label="Groovy" value="groovy"></el-option>
                    <el-option label="Python" value="python"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="脚本内容">
                  <el-input 
                    v-model="selectedElement.properties.script" 
                    type="textarea" 
                    :rows="8"
                    @input="updateElementProperties"
                  ></el-input>
                </el-form-item>
              </template>
            </template>
          </el-form>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue'
import LogicFlow from '@logicflow/core'
import { Control, Menu, SelectionSelect, Snapshot } from '@logicflow/extension'
import { Save, Delete, ZoomIn, ZoomOut, FullScreen } from '@element-plus/icons-vue'
import '@logicflow/core/dist/style/index.css'
import '@logicflow/extension/lib/style/index.css'

// Props
const props = defineProps({
  flowData: {
    type: Object,
    default: () => ({})
  },
  readonly: {
    type: Boolean,
    default: false
  }
})

// Emits
const emit = defineEmits(['save', 'change'])

// Refs
const flowContainer = ref(null)
const selectedElement = ref(null)

// 流程图实例
let lf = null

// 节点类型定义
const nodeTypes = ref([
  {
    type: 'start-node',
    label: '开始',
    icon: 'el-icon-video-play',
    iconClass: 'start-icon'
  },
  {
    type: 'end-node', 
    label: '结束',
    icon: 'el-icon-video-pause',
    iconClass: 'end-icon'
  },
  {
    type: 'http-node',
    label: 'HTTP请求',
    icon: 'el-icon-link',
    iconClass: 'http-icon'
  },
  {
    type: 'condition-node',
    label: '条件判断',
    icon: 'el-icon-s-operation',
    iconClass: 'condition-icon'
  },
  {
    type: 'script-node',
    label: '脚本执行',
    icon: 'el-icon-document',
    iconClass: 'script-icon'
  },
  {
    type: 'data-node',
    label: '数据转换',
    icon: 'el-icon-s-data',
    iconClass: 'data-icon'
  }
])

// 计算属性
const nodeCount = computed(() => {
  return lf ? lf.getGraphData().nodes.length : 0
})

const edgeCount = computed(() => {
  return lf ? lf.getGraphData().edges.length : 0
})

/**
 * 初始化LogicFlow
 */
const initLogicFlow = () => {
  if (!flowContainer.value) return
  
  lf = new LogicFlow({
    container: flowContainer.value,
    width: flowContainer.value.offsetWidth,
    height: flowContainer.value.offsetHeight,
    grid: {
      size: 20,
      visible: true,
      type: 'dot',
      config: {
        color: '#ababab',
        thickness: 1
      }
    },
    keyboard: {
      enabled: true
    },
    style: {
      rect: {
        rx: 5,
        ry: 5,
        strokeWidth: 2
      },
      circle: {
        strokeWidth: 2
      },
      nodeText: {
        overflowMode: 'autoWrap',
        lineHeight: 1.2,
        fontSize: 12
      },
      edgeText: {
        textAnchor: 'middle',
        dominantBaseline: 'middle'
      }
    },
    edgeType: 'polyline',
    hoverOutline: false,
    nodeSelectedOutline: false,
    hideAnchors: false,
    autoExpand: false
  })
  
  // 注册插件
  lf.use(Control)
  lf.use(Menu)
  lf.use(SelectionSelect)
  lf.use(Snapshot)
  
  // 注册自定义节点
  registerCustomNodes()
  
  // 绑定事件
  bindEvents()
  
  // 加载初始数据
  if (props.flowData && Object.keys(props.flowData).length > 0) {
    lf.render(props.flowData)
  }
  
  // 设置只读模式
  if (props.readonly) {
    lf.setProperties({
      isSilentMode: true,
      stopScrollGraph: true,
      stopZoomGraph: true,
      stopMoveGraph: true
    })
  }
}

/**
 * 注册自定义节点
 */
const registerCustomNodes = () => {
  // 开始节点
  lf.register('start-node', ({ RectNode, RectNodeModel }) => {
    class StartNode extends RectNode {}
    class StartNodeModel extends RectNodeModel {
      initNodeData(data) {
        super.initNodeData(data)
        this.width = 100
        this.height = 40
        this.radius = 20
        this.text.value = data.text || '开始'
        this.fill = '#67C23A'
        this.stroke = '#67C23A'
        this.color = '#FFFFFF'
      }
      
      getDefaultAnchor() {
        return [
          { x: this.x + this.width / 2, y: this.y + this.height / 2, id: `${this.id}_right` }
        ]
      }
    }
    return {
      view: StartNode,
      model: StartNodeModel
    }
  })
  
  // 结束节点
  lf.register('end-node', ({ RectNode, RectNodeModel }) => {
    class EndNode extends RectNode {}
    class EndNodeModel extends RectNodeModel {
      initNodeData(data) {
        super.initNodeData(data)
        this.width = 100
        this.height = 40
        this.radius = 20
        this.text.value = data.text || '结束'
        this.fill = '#F56C6C'
        this.stroke = '#F56C6C'
        this.color = '#FFFFFF'
      }
      
      getDefaultAnchor() {
        return [
          { x: this.x - this.width / 2, y: this.y, id: `${this.id}_left` }
        ]
      }
    }
    return {
      view: EndNode,
      model: EndNodeModel
    }
  })
  
  // HTTP请求节点
  lf.register('http-node', ({ RectNode, RectNodeModel }) => {
    class HttpNode extends RectNode {}
    class HttpNodeModel extends RectNodeModel {
      initNodeData(data) {
        super.initNodeData(data)
        this.width = 120
        this.height = 50
        this.radius = 5
        this.text.value = data.text || 'HTTP请求'
        this.fill = '#409EFF'
        this.stroke = '#409EFF'
        this.color = '#FFFFFF'
        
        // 初始化属性
        if (!this.properties) {
          this.properties = {
            method: 'GET',
            url: '',
            headers: '{}',
            description: ''
          }
        }
      }
    }
    return {
      view: HttpNode,
      model: HttpNodeModel
    }
  })
  
  // 条件判断节点
  lf.register('condition-node', ({ PolygonNode, PolygonNodeModel }) => {
    class ConditionNode extends PolygonNode {}
    class ConditionNodeModel extends PolygonNodeModel {
      initNodeData(data) {
        super.initNodeData(data)
        this.width = 100
        this.height = 60
        this.text.value = data.text || '条件判断'
        this.fill = '#E6A23C'
        this.stroke = '#E6A23C'
        this.color = '#FFFFFF'
        
        // 菱形节点的点坐标
        this.points = [
          [this.x, this.y - this.height / 2],
          [this.x + this.width / 2, this.y],
          [this.x, this.y + this.height / 2],
          [this.x - this.width / 2, this.y]
        ]
        
        // 初始化属性
        if (!this.properties) {
          this.properties = {
            condition: '',
            description: ''
          }
        }
      }
    }
    return {
      view: ConditionNode,
      model: ConditionNodeModel
    }
  })
  
  // 脚本执行节点
  lf.register('script-node', ({ RectNode, RectNodeModel }) => {
    class ScriptNode extends RectNode {}
    class ScriptNodeModel extends RectNodeModel {
      initNodeData(data) {
        super.initNodeData(data)
        this.width = 120
        this.height = 50
        this.radius = 5
        this.text.value = data.text || '脚本执行'
        this.fill = '#909399'
        this.stroke = '#909399'
        this.color = '#FFFFFF'
        
        // 初始化属性
        if (!this.properties) {
          this.properties = {
            language: 'javascript',
            script: '',
            description: ''
          }
        }
      }
    }
    return {
      view: ScriptNode,
      model: ScriptNodeModel
    }
  })
  
  // 数据转换节点
  lf.register('data-node', ({ RectNode, RectNodeModel }) => {
    class DataNode extends RectNode {}
    class DataNodeModel extends RectNodeModel {
      initNodeData(data) {
        super.initNodeData(data)
        this.width = 120
        this.height = 50
        this.radius = 5
        this.text.value = data.text || '数据转换'
        this.fill = '#9C27B0'
        this.stroke = '#9C27B0'
        this.color = '#FFFFFF'
        
        // 初始化属性
        if (!this.properties) {
          this.properties = {
            transformation: '',
            description: ''
          }
        }
      }
    }
    return {
      view: DataNode,
      model: DataNodeModel
    }
  })
}

/**
 * 绑定事件
 */
const bindEvents = () => {
  // 节点选中事件
  lf.on('node:click', ({ data }) => {
    selectedElement.value = { ...data }
  })
  
  // 边选中事件
  lf.on('edge:click', ({ data }) => {
    selectedElement.value = { ...data }
  })
  
  // 画布点击事件
  lf.on('blank:click', () => {
    selectedElement.value = null
  })
  
  // 数据变化事件
  lf.on('history:change', () => {
    emit('change', lf.getGraphData())
  })
  
  // 拖拽添加节点事件
  lf.on('node:add', ({ data }) => {
    emit('change', lf.getGraphData())
  })
  
  // 删除节点事件
  lf.on('node:delete', ({ data }) => {
    emit('change', lf.getGraphData())
  })
  
  // 连线事件
  lf.on('edge:add', ({ data }) => {
    emit('change', lf.getGraphData())
  })
  
  // 删除连线事件
  lf.on('edge:delete', ({ data }) => {
    emit('change', lf.getGraphData())
  })
}

/**
 * 拖拽开始处理
 */
const handleDragStart = (event, node) => {
  event.dataTransfer.setData('application/logicflow-node', JSON.stringify(node))
}

/**
 * 更新元素文本
 */
const updateElementText = () => {
  if (selectedElement.value && lf) {
    lf.updateText(selectedElement.value.id, selectedElement.value.text)
    emit('change', lf.getGraphData())
  }
}

/**
 * 更新元素属性
 */
const updateElementProperties = () => {
  if (selectedElement.value && lf) {
    lf.setProperties(selectedElement.value.id, selectedElement.value.properties)
    emit('change', lf.getGraphData())
  }
}

/**
 * 保存流程
 */
const saveFlow = () => {
  if (lf) {
    const flowData = lf.getGraphData()
    emit('save', flowData)
  }
}

/**
 * 清空画布
 */
const clearFlow = () => {
  if (lf) {
    lf.clearData()
    selectedElement.value = null
    emit('change', lf.getGraphData())
  }
}

/**
 * 放大
 */
const zoomIn = () => {
  if (lf) {
    lf.zoom(true)
  }
}

/**
 * 缩小
 */
const zoomOut = () => {
  if (lf) {
    lf.zoom(false)
  }
}

/**
 * 适应画布
 */
const fitView = () => {
  if (lf) {
    lf.fitView()
  }
}

/**
 * 获取流程数据
 */
const getFlowData = () => {
  return lf ? lf.getGraphData() : null
}

/**
 * 设置流程数据
 */
const setFlowData = (data) => {
  if (lf && data) {
    lf.render(data)
  }
}

// 暴露方法给父组件
defineExpose({
  getFlowData,
  setFlowData,
  saveFlow,
  clearFlow
})

// 生命周期
onMounted(() => {
  initLogicFlow()
  
  // 监听拖拽事件
  if (flowContainer.value) {
    flowContainer.value.addEventListener('drop', (event) => {
      event.preventDefault()
      const nodeData = JSON.parse(event.dataTransfer.getData('application/logicflow-node'))
      
      if (nodeData && lf) {
        const rect = flowContainer.value.getBoundingClientRect()
        const x = event.clientX - rect.left
        const y = event.clientY - rect.top
        
        lf.addNode({
          type: nodeData.type,
          x,
          y,
          text: nodeData.label
        })
      }
    })
    
    flowContainer.value.addEventListener('dragover', (event) => {
      event.preventDefault()
    })
  }
})

onUnmounted(() => {
  if (lf) {
    lf.destroy()
  }
})
</script>

<style scoped>
.flow-designer {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #f5f5f5;
}

.flow-toolbar {
  height: 50px;
  background: #fff;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
}

.flow-info {
  display: flex;
  gap: 16px;
  font-size: 14px;
  color: #606266;
}

.flow-container {
  flex: 1;
  display: flex;
  height: calc(100% - 50px);
}

.node-panel {
  width: 200px;
  background: #fff;
  border-right: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;
}

.panel-title {
  height: 40px;
  line-height: 40px;
  padding: 0 16px;
  background: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
  font-weight: 500;
  font-size: 14px;
}

.node-list {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
}

.node-item {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  margin-bottom: 8px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  cursor: grab;
  transition: all 0.3s;
}

.node-item:hover {
  border-color: #409eff;
  background: #f0f9ff;
}

.node-item:active {
  cursor: grabbing;
}

.node-icon {
  width: 24px;
  height: 24px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 8px;
  color: #fff;
  font-size: 12px;
}

.start-icon { background: #67C23A; }
.end-icon { background: #F56C6C; }
.http-icon { background: #409EFF; }
.condition-icon { background: #E6A23C; }
.script-icon { background: #909399; }
.data-icon { background: #9C27B0; }

.node-label {
  font-size: 12px;
  color: #303133;
}

.canvas-container {
  flex: 1;
  position: relative;
}

.flow-canvas {
  width: 100%;
  height: 100%;
}

.property-panel {
  width: 300px;
  background: #fff;
  border-left: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;
}

.property-content {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
}

/* LogicFlow样式覆盖 */
:deep(.lf-canvas-overlay) {
  background: #fafafa;
}

:deep(.lf-grid) {
  opacity: 0.3;
}

:deep(.lf-node-text) {
  font-size: 12px;
  font-weight: 500;
}

:deep(.lf-edge-text) {
  font-size: 11px;
  fill: #606266;
}
</style>